package me.firstapp.service.weixin.member.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import me.firstapp.common.exception.ServiceException;
import me.firstapp.common.exception.StatusHouse;
import me.firstapp.common.utils.DateUtils;
import me.firstapp.common.utils.MD5Utils;
import me.firstapp.common.utils.Page;
import me.firstapp.common.utils.StrUtils;
import me.firstapp.module.weixin.jinbi.JinBiAccount;
import me.firstapp.module.weixin.jinbi.JinBiAccountTrace;
import me.firstapp.module.weixin.member.Member;
import me.firstapp.module.weixin.order.SpreadOrder;
import me.firstapp.module.weixin.system.ThisSystem;
import me.firstapp.module.weixin.weibi.WeiBiAccount;
import me.firstapp.module.weixin.weibi.WeiBiAccountTrace;
import me.firstapp.module.weixin.weibi.WeiBiAccountTrace.ChangeType;
import me.firstapp.repository.weixin.jinbi.JinBiAccountRepository;
import me.firstapp.repository.weixin.jinbi.JinBiAccountTraceRepository;
import me.firstapp.repository.weixin.member.MemberRepository;
import me.firstapp.repository.weixin.order.SpreadOrderRepository;
import me.firstapp.repository.weixin.system.ThisSystemRepository;
import me.firstapp.repository.weixin.weibi.WeiBiAccountRepository;
import me.firstapp.repository.weixin.weibi.WeiBiAccountTraceRepository;
import me.firstapp.service.weixin.member.SpreadOrderService;

@Service
public class SpreadOrderServiceImpl implements SpreadOrderService {

	private static Logger logger = LoggerFactory.getLogger(SpreadOrderServiceImpl.class);

	@Autowired
	private MemberRepository memberRepository;

	@Autowired
	private SpreadOrderRepository spreadOrderRepository;

	@Autowired
	private WeiBiAccountRepository weiBiAccountRepository;

	@Autowired
	private WeiBiAccountTraceRepository weiBiAccountTraceRepository;

	@Autowired
	private JinBiAccountRepository jinBiAccountRepository;

	@Autowired
	private JinBiAccountTraceRepository jinBiAccountTraceRepository;

	@Autowired
	private ThisSystemRepository thisSystemRepository;

	@Override
	public SpreadOrder executeAdd(String openId, String beiOpenId) {
		Member member = memberRepository.findMemberByOpenId(openId);
		Member beiMember = memberRepository.findMemberByOpenId(beiOpenId);
		if (null == member || null == beiMember) {
			throw new ServiceException(StatusHouse.STATUS_MEMBER_NOT_EXIST);
		}
		SpreadOrder spreadOrder = spreadOrderRepository.findByOpenIdAndBeiOpenId(openId, beiOpenId);
		if (null == spreadOrder) {
			spreadOrder = new SpreadOrder();
			spreadOrder.setOpenId(openId);
			spreadOrder.setCardNo(member.getCardNo());
			spreadOrder.setBeiOpenId(beiOpenId);
			spreadOrder.setBeiCardNo(beiMember.getCardNo());
			spreadOrder.setCreateTime(new Date());
			spreadOrder.setSettleFlag(SpreadOrder.SETTLE_FLAG_NOT);
			spreadOrder.setGivePoint(BigDecimal.ZERO);
			spreadOrder.setGiveJinBi(BigDecimal.ZERO);
			spreadOrderRepository.save(spreadOrder);
		}
		return spreadOrder;
	}

	@Override
	public SpreadOrder executeSettle(SpreadOrder spreadOrder) {
		if (SpreadOrder.SETTLE_FLAG_YES == spreadOrder.getSettleFlag()) {
			return spreadOrder;
		}
		Member beiMember = memberRepository.findMemberByOpenId(spreadOrder.getBeiOpenId());
		Member member = memberRepository.findMemberByOpenId(spreadOrder.getOpenId());
		if (Member.STATUS_NO_USE == beiMember.getStatus() || Member.FOLLOW_STATUS_NO == beiMember.getFollowStatus()) {
			spreadOrder.setSettleFlag(SpreadOrder.SETTLE_FLAG_YES);
			spreadOrder.setSettleTime(new Date());
			spreadOrder.setGivePoint(BigDecimal.ZERO);
			spreadOrder.setGiveJinBi(BigDecimal.ZERO);
			spreadOrderRepository.update(spreadOrder);
			return spreadOrder;
		}
		// 如果关注的用户没有浏览过网页，则不进行结算
		if (StrUtils.isNULL(beiMember.getName()) || StrUtils.isNULL(beiMember.getAvatar())) {
			return spreadOrder;
		}
		ThisSystem thisSystem = thisSystemRepository.findThisSystem();

		// 赠送积分
		BigDecimal spreadGiveWeiBi = thisSystem.getSpreadGiveWeiBi();
		if (spreadGiveWeiBi.doubleValue() <= 0.000099) {
			spreadOrder.setGivePoint(BigDecimal.ZERO);
		} else {
			WeiBiAccount weiBiAccount = weiBiAccountRepository.findWeiBiAccountByCardNoAndOpenId(member.getCardNo(),
					member.getOpenId());
			if (!MD5Utils.verify(weiBiAccount.getBalance().doubleValue() * 10000 + "", weiBiAccount.getEncryption())) {
				logger.info("用户【" + member.getCardNo() + "】积分账户金额异常!");
				return spreadOrder;
			}
			WeiBiAccountTrace memberWeiBiAccountTrace = new WeiBiAccountTrace();
			memberWeiBiAccountTrace.setWeiBiAccountId(weiBiAccount.getId());
			memberWeiBiAccountTrace.setChangeType(ChangeType.SPREAD_ADD);
			memberWeiBiAccountTrace.setBeforeValue(weiBiAccount.getBalance());
			memberWeiBiAccountTrace.setChangeValue(spreadGiveWeiBi);
			BigDecimal memberWeiBiAfterValue = weiBiAccount.getBalance().add(spreadGiveWeiBi).setScale(4,
					RoundingMode.HALF_UP);
			memberWeiBiAccountTrace.setAfterValue(memberWeiBiAfterValue);
			memberWeiBiAccountTrace.setChangeTime(new Date());
			memberWeiBiAccountTrace.setChangeDate(Integer.valueOf(DateUtils.getDateStr(new Date(), "yyyyMMdd")));
			weiBiAccountTraceRepository.save(memberWeiBiAccountTrace);

			weiBiAccount.setBalance(memberWeiBiAfterValue);
			weiBiAccount.setEncryption(MD5Utils.generate(memberWeiBiAfterValue.doubleValue() * 10000 + ""));
			weiBiAccount.setUpdateTime(new Date());
			weiBiAccountRepository.update(weiBiAccount);

			spreadOrder.setGivePoint(spreadGiveWeiBi);
		}

		// 赠送贝币
		BigDecimal spreadGiveJinBi = thisSystem.getSpreadGiveJinBi();
		if (spreadGiveJinBi.doubleValue() <= 0.000099) {
			spreadOrder.setGiveJinBi(BigDecimal.ZERO);
		} else {
			JinBiAccount jinBiAccount = jinBiAccountRepository.findJinBiAccountByCardNoAndOpenId(member.getCardNo(),
					member.getOpenId());
			if (!MD5Utils.verify(jinBiAccount.getBalance().doubleValue() * 10000 + "", jinBiAccount.getEncryption())) {
				logger.info("用户【" + member.getCardNo() + "】贝币账户金额异常!");
				return spreadOrder;
			}
			JinBiAccountTrace jinBiAccountTrace = new JinBiAccountTrace();
			jinBiAccountTrace.setJinBiAccountId(jinBiAccount.getId());
			jinBiAccountTrace.setChangeType(me.firstapp.module.weixin.jinbi.JinBiAccountTrace.ChangeType.SPREAD_ADD);
			jinBiAccountTrace.setBeforeValue(jinBiAccount.getBalance());
			jinBiAccountTrace.setChangeValue(spreadGiveJinBi);
			BigDecimal jinBiAfterValue = jinBiAccount.getBalance().add(spreadGiveJinBi).setScale(4,
					RoundingMode.HALF_UP);
			jinBiAccountTrace.setAfterValue(jinBiAfterValue);
			jinBiAccountTrace.setChangeTime(new Date());
			jinBiAccountTrace.setChangeDate(Integer.valueOf(DateUtils.getDateStr(new Date(), "yyyyMMdd")));
			jinBiAccountTraceRepository.save(jinBiAccountTrace);

			jinBiAccount.setBalance(jinBiAfterValue);
			jinBiAccount.setEncryption(MD5Utils.generate(jinBiAfterValue.doubleValue() * 10000 + ""));
			jinBiAccount.setUpdateTime(new Date());
			jinBiAccountRepository.update(jinBiAccount);

			spreadOrder.setGiveJinBi(spreadGiveJinBi);
		}

		spreadOrder.setSettleFlag(SpreadOrder.SETTLE_FLAG_YES);
		spreadOrder.setSettleTime(new Date());
		spreadOrderRepository.update(spreadOrder);
		return spreadOrder;
	}

	@Override
	public List<SpreadOrder> findBySettleFlag(Integer settleFlag) {
		return spreadOrderRepository.findBySettleFlag(settleFlag);
	}

	@Override
	public Page<SpreadOrder> findSpreadOrderPage(Integer pageNo, Integer pageSize, Map<String, Object> searchParams,
			String sortParam, String sortType, Date startTime, Date endTime) {
		return spreadOrderRepository.findSpreadOrderPage(pageNo, pageSize, searchParams, sortParam, sortType, startTime,
				endTime);
	}

}
